﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using BookShop.DAL;
using BookShop.DTO;
using BookShop.Library.Constant;

namespace BookShop.BLL
{
    public class OrderService
    {
        public static Order Add(Order order)
        {
            using (var repository = new OrderRepository())
            {
                return repository.Add(order);
            }
        }

        public static Order Update(Order order)
        {
            using (var repository = new OrderRepository())
            {
                return repository.Update(order);
            }
        }

        public static bool Delete(long orderId)
        {
            using (var repository = new OrderRepository())
            {
                var order = GetById(orderId);
                if (order == null)
                {
                    return false;
                }
                order.Status = OrderStatus.Inactive;
                order = repository.Update(order);
                return order != null;
            }
        }

        public static List<Order> GetByCustomerId(long customerId)
        {
            using (var repository = new OrderRepository())
            {
                return repository.FindAll(c => c.CustomerId == customerId).ToList();
            }
        }

        public static Order GetById(long orderId)
        {
            using (var repository = new OrderRepository())
            {
                return repository.Find(o => o.Id == orderId);
            }
        }

        public static bool GetPeriodIncome(long orderId, int period, out double income)
        {
            using (var repository = new OrderRepository())
            {
                var order = GetById(orderId);
                if (order == null)
                {
                    income = 0;
                    return false;
                }
                var orderList = repository.FindAll(o => o.CreateTime.Year == DateTime.Now.Year).ToList();
                if (period == TimePeriod.Month)
                {
                    orderList = orderList.FindAll(o => o.CreateTime.Month == DateTime.Now.Month).ToList();
                }
                income = orderList.Sum(o => o.TotalPrice != null ? o.TotalPrice.Value : 0);
                return true;
            }
        }

        public static List<Order> Search(long? orderId, long? customerId, string fromCreateTime, string toCreateTime,
             int? status, string fromTotalPrice, string toTotalPrice, int page, int pageSize, out int count)
        {
            var repository = new OrderRepository();
            var returnList = new List<Order>();
            if (orderId.HasValue)
            {
                var order = GetById(orderId.Value);
                if (order != null)
                {
                    returnList.Add(order);
                }
            }
            else
            {
                returnList = repository.GetAll().ToList();
                if (customerId.HasValue)
                {
                    returnList = returnList.FindAll(o => o.CustomerId == customerId.Value);
                }
                DateTime newFromCreateTime;
                var isValidFromCreateTime = DateTime.TryParse(fromCreateTime, CultureInfo.CreateSpecificCulture("vi-VN"),
                    DateTimeStyles.None, out newFromCreateTime);
                DateTime newToCreateTime;
                var isValidToCreateTime = DateTime.TryParse(toCreateTime, CultureInfo.CreateSpecificCulture("vi-VN"),
                    DateTimeStyles.None, out newToCreateTime);
                if (isValidFromCreateTime && isValidToCreateTime)
                {
                    returnList =
                        returnList.FindAll(o => o.CreateTime >= newFromCreateTime && o.CreateTime <= newToCreateTime);
                }
                if (isValidFromCreateTime && !isValidToCreateTime)
                {
                    returnList =
                        returnList.FindAll(o => o.CreateTime >= newFromCreateTime);
                }
                if (!isValidFromCreateTime && isValidToCreateTime)
                {
                    returnList =
                        returnList.FindAll(o => o.CreateTime <= newToCreateTime);
                }
                double newFromTotalPrice;
                var isValidFromTotalPrice = double.TryParse(fromTotalPrice, NumberStyles.AllowDecimalPoint,
                    CultureInfo.CreateSpecificCulture("en-US"), out newFromTotalPrice);
                double newToTotalPrice;
                var isValidToTotalPrice = double.TryParse(toTotalPrice, NumberStyles.AllowDecimalPoint,
                    CultureInfo.CreateSpecificCulture("en-US"), out newToTotalPrice);
                if (isValidFromTotalPrice && isValidToTotalPrice)
                {
                    returnList =
                        returnList.FindAll(o => o.TotalPrice >= newFromTotalPrice && o.TotalPrice <= newToTotalPrice);
                }
                if (isValidFromTotalPrice && !isValidToTotalPrice)
                {
                    returnList =
                        returnList.FindAll(o => o.TotalPrice >= newFromTotalPrice);
                }
                if (!isValidFromTotalPrice && isValidToTotalPrice)
                {
                    returnList =
                        returnList.FindAll(o => o.TotalPrice <= newToTotalPrice);
                }
                if (status.HasValue)
                {
                    returnList = returnList.FindAll(o => o.Status == status.Value);
                }
            }
            count = returnList.Count;
            return returnList.Skip((page - 1) * pageSize).Take(pageSize).ToList();
        }

        public static double GetTotalPrice(long orderId)
        {
            var order = GetById(orderId);
            var totalPrice = order == null ? 0 : OrderDetailService.GetByOrderId(orderId).Sum(d => d.TotalPrice.HasValue ? d.TotalPrice.Value : 0);
            return totalPrice;
        }
    }
}
